<?php if (!defined('BASEPATH'))exit('No direct script access allowed');

include_once 'ExceptionDAO.php';
include_once 'util/MapError.php';
include_once 'TORelatorio.php';

/**
 * DAO para operações de banco para relatório
 * 
 * @author Douglas Rafael
 */
class DAORelatorio extends CI_Model {
    
    /**
     * TOTAL DE EMPRESTADOS. DE ACORDO COM O ANO E MES
     *  - Se o mês for NULL será todos os meses do ano.
     * 
     * @param  string   $year    Ano da busca. Caso necessite mais de um ano separe por virgula. Ex. 2013, 2012
     * @param  string   $month   Mês da busca. Caso necessite mais de um mês separe por virgula. Ex. 1, 2, 3, 4, 5, 6
     * @return array             Array de Objeto
     * @throws ExceptionDAO
     * @throws Exception
     */
    public function get_amout_loan($year, $month) {
        try {
            $this->db->select('EXTRACT(MONTH FROM emprestimo.data_saida) AS mes, COUNT(emprestimo.id) AS total');
            $this->db->where("EXTRACT(YEAR FROM emprestimo.data_saida) IN($year)");
            $this->db->where("EXTRACT(MONTH FROM emprestimo.data_saida) IN($month)");
            $this->db->group_by('mes');
            $result = $this->db->get('emprestimo');
            
            //Caso ocorra erro no select
            if (!$result) {
                throw new Exception('Ocorreu um erro de banco de dados ao tentar consultar relatório.');
            } else {
                return $result->result();
            }
        } catch (Exception $e) {
            throw new ExceptionDAO($e->getMessage());
        }
    }
    
    /**
     * Total de empréstimos de acordo com o ano e mes
     * 
     * @param  string   $year    Ano da busca. Caso necessite mais de um ano separe por virgula. Ex. 2013, 2012
     * @param  string   $month   Mês da busca. Caso necessite mais de um mês separe por virgula. Ex. 1, 2, 3, 4, 5, 6
     * @return int               Total da busca
     * @throws ExceptionDAO
     * @throws Exception
     */
    public function amount_loan($year, $month) {
        try {
            $this->db->select('emprestimo.id');
            $this->db->where("EXTRACT(YEAR FROM emprestimo.data_saida) IN($year)");
            $this->db->where("EXTRACT(MONTH FROM emprestimo.data_saida) IN($month)");
            $result = $this->db->get('emprestimo');
            
            //Caso ocorra erro no select
            if (!$result) {
                throw new Exception('Ocorreu um erro de banco de dados ao tentar consultar total de empréstimos para relatório.');
            } else {
                return count($result->result());
            }
        } catch (Exception $e) {
            throw new ExceptionDAO($e->getMessage());
        }
    }
    
    /**
     * Total de itens emprestados de acorco com o ano, mes e tipo
     * 
     * @param  string   $year       Ano da busca. Caso necessite mais de um ano separe por virgula. Ex. 2013, 2012
     * @param  string   $month      Mês da busca. Caso necessite mais de um mês separe por virgula. Ex. 1, 2, 3, 4, 5, 6
     * @param  string   $type_item  Tipo do item (Livro, Magazine, midia). Seo valor for NULL será todos os tipos
     * @return int      valor da consulta
     * @throws ExceptionDAO
     * @throws Exception
     */
    public function amount_itens_loan($year = NULL, $month = NULL, $type_item = NULL) {
        try {
            $this->db->select('SUM(ei.total) AS total');
            $this->db->join('emprestimo_has_item ei', 'ei.emprestimo_id = emprestimo.id');
            $year != NULL ? $this->db->where("EXTRACT(YEAR FROM emprestimo.data_saida) IN($year)") : '';
            $month != NULL ? $this->db->where("EXTRACT(MONTH FROM emprestimo.data_saida) IN($month)") : '';
            
            /** Se o tipo do item for igual a null, a busca será feita por todos os tipos **/
            if($type_item != NULL) {
                $this->db->join('item', 'item.codigo = ei.item_codigo'); 
                $this->db->where('item.item_tipo_id', $type_item); 
            }
            $this->db->group_by('ei.emprestimo_id');
            $result = $this->db->get('emprestimo');
            
            //Caso ocorra erro no select
            if (!$result) {
                throw new Exception('Ocorreu um erro de banco de dados ao tentar consultar total de empréstimos para relatório.');
            } else {
                $total = array();
                foreach ($result->result() as $value){
                    array_push($total, $value->total);
                }
                return array_sum($total);
            }
        } catch (Exception $e) {
            throw new ExceptionDAO($e->getMessage());
        }
    }


    /**
     * Total de ITENS (livro, magazine, mídia) emprestados de acordo com ano e mês
     * 
     * @param  string   $year       Ano da busca. Caso necessite mais de um ano separe por virgula. Ex. 2013, 2012
     * @param  string   $month      Mês da busca. Caso necessite mais de um mês separe por virgula. Ex. 1, 2, 3, 4, 5, 6...
     * @param  string   $type_item  Tipo do item (Livro, Magazine, midia).
     * @return array    Array de objeto contendo os dados
     * @throws ExceptionDAO
     * @throws Exception
     */
    public function get_amout_item_loan($year, $month, $type_item) {
        try {
            $this->db->select('EXTRACT(MONTH FROM emprestimo.data_saida) AS mes, SUM(ei.total) AS total');
            $this->db->join('emprestimo_has_item ei', 'ei.emprestimo_id = emprestimo.id');
            $this->db->join('item', 'item.codigo = ei.item_codigo');
            $this->db->where("EXTRACT(YEAR FROM emprestimo.data_saida) IN($year)");
            $this->db->where("EXTRACT(MONTH FROM emprestimo.data_saida) IN($month)");
            $this->db->where('item.item_tipo_id', $type_item);
            $this->db->group_by('mes');
            $result = $this->db->get('emprestimo');
            
            //Caso ocorra erro no select
            if (!$result) {
                throw new Exception('Ocorreu um erro de banco de dados ao tentar consultar relatório de empréstimos.');
            } else {
                return $result->result();
            }
        } catch (Exception $e) {
            throw new ExceptionDAO($e->getMessage());
        }
    }
    
    
    /**
     * Anos em que ocorreram emprestimos, multas
     * 
     * @return array        Resultado da cosulta, apenas os anos
     * @throws ExceptionDAO
     * @throws Exception
     */
    public function year_all() {
        try {
            $this->db->select("EXTRACT(YEAR FROM data_saida) AS ano");
            $this->db->group_by('ano');
            $this->db->order_by('ano DESC');
            $result = $this->db->get('emprestimo');

            $this->db->select("EXTRACT(YEAR FROM data_cobranca) AS ano_multa");
            $this->db->group_by('ano_multa');
            $this->db->order_by('ano_multa DESC');
            $result2 = $this->db->get('multa');

            if (!$result) {
                throw new Exception('Ocorreu um erro de banco de dados ao tentar listar anos');
            } else {
                $anos = array(0 => 'Todos os anos');
                $ano_atual = date('Y');
                foreach ($result->result() as $ano) {
                    $anos[$ano->ano] = $ano->ano;
                }

                // Se conter dados
                if (count($result2->result()) > 0) {
                    foreach ($result2->result() as $ano_multa) {
                        $anos[$ano_multa->ano_multa] = $ano_multa->ano_multa;
                    }
                }else if(count($anos) == 1) {
                    $anos[$ano_atual] = $ano_atual;
                }

                return $anos;
            }
        } catch (Exception $e) {
            throw new ExceptionDAO($e->getMessage());
        }
    }
    
    /**
     * Retorna a soma das multas separadas por mês e ano e status
     * 
     * @param  string   $year       Ano da busca. Caso necessite mais de um ano separe por virgula. Ex. 2013, 2012
     * @param  string   $month      Mês da busca. Caso necessite mais de um mês separe por virgula. Ex. 1, 2, 3, 4, 5, 6
     * @param  bool     $status     Status da multa. TRUE para ativa e FALSE para INATIVA (paga)
     * @return array                Array de objeto contendo os dados
     * @throws ExceptionDAO
     * @throws Exception
     */
    public function amout_sum_fine($year, $month, $status) {
        try {
            $this->db->select('EXTRACT(MONTH FROM data_cobranca) AS mes, SUM(valor) AS total');
            $this->db->where("EXTRACT(YEAR FROM data_cobranca) IN($year)");
            $this->db->where("EXTRACT(MONTH FROM data_cobranca) IN($month)");
            $this->db->where('status', $status);
            $this->db->group_by('mes');
            $result = $this->db->get('multa');
            
            //Caso ocorra erro no select
            if (!$result) {
                throw new Exception('Ocorreu um erro de banco de dados ao tentar consultar relatório de multas.');
            } else {
                return $result->result();
            }
        } catch (Exception $e) {
            throw new ExceptionDAO($e->getMessage());
        }
    }
    
    /**
     * Efetua busca dos usuário que mais realizarm empréstimos no período selecionado
     * 
     * @param  string   $year       Ano da busca. Caso necessite mais de um ano separe por virgula. Ex. 2013, 2012
     * @param  string   $month      Mês da busca. Caso necessite mais de um mês separe por virgula. Ex. 1, 2, 3, 4, 5, 6...
     * @param  int      $limit              Limiti da consulta. Se for igual a NULL, não terá limit
     * @return array    Array contendo os dados da consulta
     * @throws ExceptionDAO
     * @throws Exception
     */
    public function history_user_active_loan($year = NULL, $month = NULL, $limit = NULL) {
        try {
            $this->db->select('usuario.nome, usuario.sobrenome, COUNT(usuario.id) AS total');
            $this->db->join('usuario', 'usuario.id = emprestimo.usuario_id');
            $year != NULL ? $this->db->where("EXTRACT(YEAR FROM emprestimo.data_saida) IN($year)") : '';
            $month != NULL ? $this->db->where("EXTRACT(MONTH FROM emprestimo.data_saida) IN($month)") : '';
            $this->db->group_by('usuario.id');
            $this->db->order_by('total DESC, usuario.nome ASC, usuario.data_cadastro ASC');
            $limit != NULL ? $this->db->limit($limit) : '';
            $result = $this->db->get('emprestimo');
            
            //Caso ocorra erro no select
            if (!$result) {
                throw new Exception('Ocorreu um erro de banco de dados ao tentar consultar relatório de usuários mais ativos.');
            } else {
                return $result->result();
            }
        } catch (Exception $e) {
            throw new ExceptionDAO($e->getMessage());
        }
    }
    
    
    /**
     * Efetua busca dos usuário que mais foram multados no período selecionado
     * 
     * @param  string   $year       Ano da busca. Caso necessite mais de um ano separe por virgula. Ex. 2013, 2012
     * @param  string   $month      Mês da busca. Caso necessite mais de um mês separe por virgula. Ex. 1, 2, 3, 4, 5, 6...
     * @param  int      $limit              Limiti da consulta. Se for igual a NULL, não terá limit
     * @return array    Array contendo os dados da consulta
     * @throws ExceptionDAO
     * @throws Exception
     */
    public function history_user_fine($year = NULL, $month = NULL, $limit = NULL) {
        try {
            $this->db->select('usuario.nome, usuario.sobrenome, SUM(multa.valor) AS valor, COUNT(usuario.id) AS total');
            $this->db->join('usuario', 'usuario.id = multa.usuario_id');
            $this->db->where("EXTRACT(YEAR FROM data_cobranca) IN($year)");
            $year != NULL ? $this->db->where("EXTRACT(YEAR FROM multa.data_cobranca) IN($year)") : '';
            $month != NULL ? $this->db->where("EXTRACT(MONTH FROM multa.data_cobranca) IN($month)") : '';     
            $this->db->group_by('usuario.id');
            $this->db->order_by('total DESC, usuario.nome ASC, usuario.data_cadastro ASC');
            $limit != NULL ? $this->db->limit($limit) : '';
            $result = $this->db->get('multa');
            
            //Caso ocorra erro no select
            if (!$result) {
                throw new Exception('Ocorreu um erro de banco de dados ao tentar consultar relatório de usuários que sofreram mais multas.');
            } else {
                return $result->result();
            }
        } catch (Exception $e) {
            throw new ExceptionDAO($e->getMessage());
        }
    }
    
    
    /**
     * Efetua busca dos itens que mais foram emprestados no período selecionado
     * 
     * @param  string   $year       Ano da busca. Caso necessite mais de um ano separe por virgula. Ex. 2013, 2012
     * @param  string   $month      Mês da busca. Caso necessite mais de um mês separe por virgula. Ex. 1, 2, 3, 4, 5, 6...
     * @param  int      $limit              Limiti da consulta. Se for igual a NULL, não terá limit
     * @return array    Array contendo os dados da consulta
     * @throws ExceptionDAO
     * @throws Exception
     */
    public function history_itens_active_loan($year = NULL, $month = NULL, $limit = NULL) {
        try {
            $this->db->select('item.titulo, item_tipo.nome AS tipo, COUNT(item_codigo) AS total');
            $this->db->join('emprestimo', 'emprestimo.id = emprestimo_id');
            $this->db->join('item', 'item.codigo = item_codigo');
            $this->db->join('item_tipo', 'item.item_tipo_id = item_tipo.id');
            $year != NULL ? $this->db->where("EXTRACT(YEAR FROM emprestimo.data_saida) IN($year)") : '';
            $month != NULL ? $this->db->where("EXTRACT(MONTH FROM emprestimo.data_saida) IN($month)") : '';
            $this->db->group_by('item_codigo');
            $this->db->order_by('total DESC, item.titulo ASC');
            $limit != NULL ? $this->db->limit($limit) : '';
            $result = $this->db->get('emprestimo_has_item');

            //Caso ocorra erro no select
            if (!$result) {
                throw new Exception('Ocorreu um erro de banco de dados ao tentar consultar relatório de itens mais empréstados.');
            } else {
                return $result->result();
            }
        } catch (Exception $e) {
            throw new ExceptionDAO($e->getMessage());
        }
    }
    
}